【SwiftUI】動く破線の枠線で囲まれたViewを作ってみた
ペイントアプリでよく見かける動く破線の枠線を作ってみたかったので作ってみることにしました。
作ったもの
この記事ではこの作り方について説明していきます。
環境
- Xcode 13.3
点線の枠線を作る
まずは普通の破線の枠線で囲まれたViewを作ります。
var body: some View { Rectangle() .stroke(style: StrokeStyle(dash: [4, 2])) .frame(width: 200, height: 200) }
stroke(style:)
で、Rectangle()
のストロークをコピーして、そのストロークのStrokeStyle
を定義してあげるだけで破線で囲まれたViewが作れます。
StrokeStyle
のdash
の配列[4, 2]
ですが、4
の箇所が破線部分の長さを示しており、2
の箇所が破線の空白の部分を示しています。
プレビュー
StrokeStyle
StrokeStyle
のdash
については説明しましたが、他のプロパティもあります。
@frozen public struct StrokeStyle : Equatable { /// ストロークされたパスの長さ public var lineWidth: CGFloat /// 線の終点のスタイル public var lineCap: CGLineCap /// 線の結合部分のスタイル public var lineJoin: CGLineJoin /// 結合箇所をmiterにするかbevelにするかを決めるためのしきい値 public var miterLimit: CGFloat /// 破線を形成する為の色付け部分と空白部分の長さ public var dash: [CGFloat] /// 破線のスタート地点までの距離 public var dashPhase: CGFloat
miter
、bevel
についてはこちらのmiterLimitの説明が分かりやすかったです。
今回は上記のプロパティの内dashPhase
の値を変更することで移動しているような破線を表現していきます。
動く破線を表現する
コード
import SwiftUI struct ContentView: View { /// 破線のスタート地点を変更する為のプロパティ @State private var dashPhase: CGFloat = 0 /// Timerのカウントを保持するプロパティ @State private var timerCount: CGFloat = 0 /// 0.1秒毎に`dashPhase`を変更処理を実行する為のTimer private let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect() var body: some View { Rectangle() .stroke(style: StrokeStyle(dash: [6, 6], dashPhase: dashPhase)) .frame(width: 200, height: 200) .onReceive(timer) { _ in timerCount = timerCount > 10 ? 0 : timerCount + 1 dashPhase = timerCount } } }
プロパティ
dashPhase
では、変更された破線のスタート地点の値が代入されるので、その値をStrokeStyle
のdashPhase
に設定しています。
0.1
秒毎に処理を実行できるtimer
を用意し、そのTimerのカウントに応じて、dashPhase
を変更する為、timerCount
でカウントを保持します。
onReceive(timer)
onReceive
の第一引数にはtimer
を渡すことでクロージャーの処理が0.1
秒毎に呼ばれます。
.onReceive(timer) { _ in timerCount = timerCount > 10 ? 0 : timerCount + 1 dashPhase = timerCount }
実行している処理としては、timerCount
が10
より大きいなら0
に初期化して元の状態に戻して、timerCount
が10
以下なら1
を加算しています。そのtimerCount
の値をdashPhase
に代入することで破線が移動しているような動きを表現しています。
dashPhase
最初の説明でdashPhase
は破線のスタート地点までの距離を示すプロパティと記載したのですが、つまりはオフセットなので、この値が増える毎に最初の破線の位置が移動していきます。今回は10
という値をしきい値にしましたが、この値は破線の長さによって変更してきます。
以上で動く破線の枠線の四角いViewの完成です。
おわりに
思ったより少ないコードで実現できてびっくりしました。頭に描いたものが作れると楽しいですね。
これからも作って遊ぼうしていきたいと思います。